/*
 * dwr_packetdb.c
 *
 *  Created on: 07/05/2013
 *      Author: jose
 */


#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <dbi/dbi.h>
#include "dwr_packetdb.h"

void
dwr_packet_save_string_to_struct(DwrPacket * pkt, DwrString ** field,
		const char * str, unsigned str_len)
{
	assert(pkt);
	/* TODO a descomentar. Se deja descomentado para ver ejecucion del OpenDPI_Demo */
	//assert(field);
	assert(str);
	assert(str_len > 0);

	(*field) = dwr_string_create_with_len(str, str_len);
	if (!(*field))
		return;

	pkt->saved = 1;
}

/* TODO definir shift o no de direcciones. ver Endiannes */
void
dwr_packet_save_unsigned_to_struct(DwrPacket * pkt, unsigned * field,
		unsigned value)
{
	assert(pkt);

	(*field) = value&255;
	(*field) = (*field) << 8;
	(*field) |= value >> 8;

	pkt->saved = 1;
}

/* TODO funcion para guardar unsigned a struct */

DwrPacket *
dwr_packet_create()
{
	DwrPacket * pkt;

	pkt = (DwrPacket *) calloc(1, sizeof(DwrPacket));

	return pkt;
}

void
dwr_packet_free_members(DwrPacket * pkt)
{
	assert(pkt);

	free(pkt->http.accept);
	free(pkt->http.accept_encoding);
	free(pkt->http.cache_control);
	free(pkt->http.date);
	free(pkt->http.host);
	free(pkt->http.method);
	free(pkt->http.referer);
	free(pkt->http.resource);
	free(pkt->http.user_agent);
	free(pkt->http.version);

	if (pkt->ip.dest_ip.address)
		free(pkt->ip.dest_ip.address->text);
	if (pkt->ip.dest_ip.netmask)
		free(pkt->ip.dest_ip.netmask->text);

	if (pkt->ip.source_ip.address)
		free(pkt->ip.source_ip.address->text);
	if (pkt->ip.source_ip.netmask)
		free(pkt->ip.source_ip.netmask->text);

	free(pkt->ip.dest_ip.address);
	free(pkt->ip.dest_ip.netmask);
	free(pkt->ip.source_ip.address);
	free(pkt->ip.source_ip.netmask);
}


void
dwr_packet_zero_unsigned_members(DwrPacket * pkt)
{
	assert(pkt);

	pkt->saved = 0;

	pkt->tcp.dest_port = 0;
	pkt->tcp.source_port = 0;

	pkt->timestamp.year = 0;
	pkt->timestamp.month = 0;
	pkt->timestamp.day = 0;
	pkt->timestamp.hour = 0;
	pkt->timestamp.min = 0;
	pkt->timestamp.sec = 0;
}

void
dwr_packet_null_pointers(DwrPacket * pkt)
{
	assert(pkt);

	pkt->http.accept = NULL;
	pkt->http.accept_encoding = NULL;
	pkt->http.cache_control = NULL;
	pkt->http.date = NULL;
	pkt->http.host = NULL;
	pkt->http.method = NULL;
	pkt->http.referer = NULL;
	pkt->http.resource = NULL;
	pkt->http.user_agent = NULL;
	pkt->http.version = NULL;

	if (pkt->ip.dest_ip.address)
		pkt->ip.dest_ip.address->text = NULL;
	if (pkt->ip.dest_ip.netmask)
		pkt->ip.dest_ip.netmask->text = NULL;

	if (pkt->ip.source_ip.address)
		pkt->ip.source_ip.address->text = NULL;
	if (pkt->ip.source_ip.netmask)
		pkt->ip.source_ip.netmask->text = NULL;

	pkt->ip.dest_ip.address = NULL;
	pkt->ip.dest_ip.netmask = NULL;
	pkt->ip.source_ip.address = NULL;
	pkt->ip.source_ip.netmask = NULL;
}


void
dwr_packet_print(DwrPacket * packet)
{
	/* timestamp struct */
	printf("\npacket->timestamp.day = %u", packet->timestamp.day);
	printf("\npacket->timestamp.month = %u", packet->timestamp.month);
	printf("\npacket->timestamp.year = %u", packet->timestamp.year);
	printf("\npacket->timestamp.hour = %u", packet->timestamp.hour);
	printf("\npacket->timestamp.min = %u", packet->timestamp.min);
	printf("\npacket->timestamp.sec = %u", packet->timestamp.sec);

	/* tcp struct */
	printf("\npacket->tcp.source_port = %u", packet->tcp.source_port);
	printf("\npacket->tcp.dest_port = %u", packet->tcp.dest_port);

	/* ip struct */
    if (packet->ip.source_ip.address)
    	printf("\npacket->ip.source_ip.address = %.*s", packet->ip.source_ip.address->len,
    			packet->ip.source_ip.address->text);
    if (packet->ip.source_ip.netmask)
    	printf("\npacket->ip.source_ip.netmask = %.*s", packet->ip.source_ip.netmask->len,
    			packet->ip.source_ip.netmask->text);
    if (packet->ip.dest_ip.address)
    	printf("\npacket->ip.dest_ip.address = %.*s", packet->ip.dest_ip.address->len,
    			packet->ip.dest_ip.address->text);
    if (packet->ip.dest_ip.netmask)
    	printf("\npacket->ip.dest_ip.netmask = %.*s", packet->ip.dest_ip.netmask->len,
    			packet->ip.dest_ip.netmask->text);

	/* http struct */
	if (packet->http.version)
    	printf("\npacket->http.version = %.*s", packet->http.version->len,
    			packet->http.version->text);
	if (packet->http.user_agent)
    	printf("\npacket->http.user_agent = %.*s", packet->http.user_agent->len,
    			packet->http.user_agent->text);
	if (packet->http.accept)
    	printf("\npacket->http.accept = %.*s", packet->http.accept->len,
    			packet->http.accept->text);
	if (packet->http.method)
    	printf("\npacket->http.method = %.*s", packet->http.method->len,
    			packet->http.method->text);
	if (packet->http.resource)
    	printf("\npacket->http.resource = %.*s", packet->http.resource->len,
    			packet->http.resource->text);
	if (packet->http.host)
    	printf("\npacket->http.host = %.*s", packet->http.host->len,
    			packet->http.host->text);
	if (packet->http.cache_control)
    	printf("\npacket->http.cache_control = %.*s", packet->http.cache_control->len,
    			packet->http.cache_control->text);
	if (packet->http.date)
    	printf("\npacket->http.date = %.*s", packet->http.date->len,
    			packet->http.date->text);
	if (packet->http.referer)
    	printf("\npacket->http.referer = %.*s", packet->http.referer->len,
    			packet->http.referer->text);
	if (packet->http.accept_encoding)
    	printf("\npacket->http.accept_encoding = %.*s", packet->http.accept_encoding->len,
    			packet->http.accept_encoding->text);

}


DwrString *
dwr_db_generate_insert_query(DwrPacket * packet)
{
	assert(packet);

	short int prev_field = 0, prev_value = 0;
	DwrString * insert = dwr_string_create_no_len("INSERT INTO PACKET (");
	DwrString * values = dwr_string_create_no_len(" VALUES(");
	DwrString * end_string = dwr_string_create_no_len(")");
	DwrString * end_string2 = dwr_string_create_no_len(");");

	if (!insert || !values || !end_string || !end_string2)
		return NULL;

	/* timestamp struct */
	if(packet->timestamp.day)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "day");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->timestamp.day, "%d", 11));
	}
	if(packet->timestamp.month)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "month");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->timestamp.month, "%d", 11));
	}
	if(packet->timestamp.year)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "year");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->timestamp.year, "%d", 11));
	}
	if(packet->timestamp.hour)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "hour");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->timestamp.hour, "%d", 11));
	}
	if(packet->timestamp.min)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "min");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->timestamp.min, "%d", 11));
	}
	if(packet->timestamp.sec)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "sec");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->timestamp.sec, "%d", 11));
	}

	/* tcp struct */
	if(packet->tcp.source_port)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "source_port");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->tcp.source_port, "%d", 7));
	}
	if(packet->tcp.dest_port)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "dest_port");
		values = dwr_string_concat_comma(values, &prev_value,
				dwr_char_itoa(packet->tcp.dest_port, "%d", 7));
	}

	/* ip struct */
	if(packet->ip.source_ip.address)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "source_ip");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->ip.source_ip.address));
	}
	if(packet->ip.source_ip.netmask)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "source_netmask");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->ip.source_ip.netmask));
	}
	if(packet->ip.dest_ip.address)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "dest_ip");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->ip.dest_ip.address));
	}
	if(packet->ip.dest_ip.netmask)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "dest_netmask");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->ip.dest_ip.netmask));
	}

	/* http struct */
	if(packet->http.version)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_version");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.version));
	}
	if(packet->http.user_agent)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_user_agent");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.user_agent));
	}
	if(packet->http.accept)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_accept");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.accept));
	}
	if(packet->http.method)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_method");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.method));
	}
	if(packet->http.resource)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_resource");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.resource));
	}
	if(packet->http.host)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_host");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.host));
	}
	if(packet->http.cache_control)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_cache_control");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.cache_control));
	}
	if(packet->http.date)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_date");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.date));
	}
	if(packet->http.referer)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_referer");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.referer));
	}
	if(packet->http.accept_encoding)
	{
		insert = dwr_string_concat_comma(insert, &prev_field, "http_accept_encoding");
		values = dwr_string_concat_comma_quote(values, &prev_value, dwr_string_get_text(packet->http.accept_encoding));
	}

	if(prev_field || prev_value)
	{
		insert = dwr_string_concat(insert, end_string);
		values = dwr_string_concat(values, end_string2);
	}

	insert = dwr_string_concat(insert, values);

	printf("\nINSERT (%u) %.*s", insert->len, insert->len, insert->text);
	dwr_db_push_to_db(packet, insert);

	return insert;
}






int
dwr_db_push_to_db(DwrPacket * pkt, DwrString * query)
{
	assert(pkt);
	assert(query);

	dbi_conn db;
	dbi_result result;
	int drivercount;

	drivercount = dbi_initialize(NULL);

	db = dbi_conn_new("pgsql");
	dbi_conn_set_option(db, "host", "localhost");
	dbi_conn_set_option(db, "username", "postgres");
	dbi_conn_set_option(db, "password", "postgres");
	dbi_conn_set_option(db, "dbname", "dpiwebreports");

	if (dbi_conn_connect(db) < 0)
		return 0;

	//insert query TODO comentar/descomentar para hacer insert
	dbi_conn_query(db, dwr_string_get_text(query));

	dbi_conn_close(db);
	dbi_shutdown();

	return 1;
}
